package com.sia.springcloud.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author : sia
 * @Description : excel读写工具类
 */

@Slf4j
public class POIUtil {
    private final static String xls = "xls";
    private final static String xlsx = "xlsx";

    /**
     * 读入excel文件，解析后返回
     * <p>
     * 把每行中的值作为一个数组，所有行作为一个集合返回
     *
     * @param file
     * @throws IOException
     */
    public List<String[]> parseExcel(File file) throws IOException {
        //对文件进行检查，如果不存在或者格式不正确抛出异常
        checkFile(file);

        //获得Workbook工作薄对象
        Workbook workbook = getWorkBook(file);

        //创建返回对象，把每行中的值作为一个数组，所有行作为一个集合返回
        List<String[]> list = new ArrayList<String[]>();

        if (workbook != null) {


            //这里获取的是第一张表，也只会获取这一张表，并且已经对表格进行的处理（去除空行）
            //Sheet sheet = getAccuracyContextNum(workbook);

            // 取第一个sheet
            Sheet sheet = workbook.getSheetAt(0);

            if (sheet == null) {
                return list;
            }

            //获得当前sheet的开始行
            int firstRowNum = sheet.getFirstRowNum();

            //获得当前sheet的结束行
            int lastRowNum = sheet.getLastRowNum();

            //获取sheet开始行的内容
            Row row_first = sheet.getRow(0);

            //获取开始行的列数
            int lastCellNum = row_first.getPhysicalNumberOfCells();

            //循环所有行，把包括第一行在内的所有数据都封装到String[]中
            for (int rowNum = firstRowNum; rowNum <= lastRowNum; rowNum++) {
                //获得当前行
                Row row = sheet.getRow(rowNum);
                if (row == null) {
                    continue;
                }
                //获得当前行的开始列
                int firstCellNum = row.getFirstCellNum();
                //获得当前行的列数
                String[] cells = new String[lastCellNum];
                //循环当前行
                for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
                    Cell cell = row.getCell(cellNum);
                    cells[cellNum] = getCellValue(cell);
                }
                list.add(cells);
            }

            workbook.close();
        }
        return list;
    }


    /**
     * 删除文件中的空行
     *
     * @param workbook
     * @return
     */
    public Sheet getAccuracyContextNum(Workbook workbook) {
        // 取第一个sheet
        Sheet sheet = workbook.getSheetAt(0);
        // 删除空行
        for (int i = 0; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i);
            // 删除空行
            if (this.isRowEmpty(row)) {
                int lastRowNum = sheet.getLastRowNum();
                if (i >= 0 && i < lastRowNum) {
                    // 将行号为i+1一直到行号为lastRowNum的单元格全部上移一行，以便删除i行
                    sheet.shiftRows(i + 1, lastRowNum, -1);
                }
                if (i == lastRowNum) {
                    if (row != null) {
                        sheet.removeRow(row);
                    }
                }
                i--;
            }
        }
        return sheet;
    }

    /**
     * 判断这个是不是一个空行
     *
     * @param row
     * @return
     */
    public static boolean isRowEmpty(Row row) {
        for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
            Cell cell = row.getCell(c);
            if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK)
                return false;
        }
        return true;
    }

    /**
     * 检查文件是否存在，以及格式是否正确
     *
     * @param file
     * @throws IOException
     */
    public void checkFile(File file) throws IOException {
        //判断文件是否存在
        if (null == file) {
            log.info("文件不存在！");
            throw new FileNotFoundException("文件不存在！");
        }
        //获得文件名
        String fileName = file.getName();
        //判断文件是否是excel文件
        if (!fileName.endsWith(xls) && !fileName.endsWith(xlsx)) {
            log.error(fileName + "不是excel文件");
            throw new IOException(fileName + "不是excel文件");
        }
    }

    /**
     * 将file文件转换成Workbook对象
     *
     * @param file
     * @return
     */
    public Workbook getWorkBook(File file) {
        //获得文件名
        String fileName = file.getName();
        //创建Workbook工作薄对象，表示整个excel
        Workbook workbook = null;
        try {
            //获取excel文件的io流
            InputStream is = new FileInputStream(file);
            //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
            if (fileName.endsWith(xls)) {
                //2003
                workbook = new HSSFWorkbook(is);
            } else if (fileName.endsWith(xlsx)) {
                //2007
                workbook = new XSSFWorkbook(is);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return workbook;
    }

    /**
     * 将单元格内容转化为字符串
     */
    private String getCellValue(Cell cell) {
        if (null == cell) {
            return null;
        }
        String returnValue = "";
        cell.setCellType(Cell.CELL_TYPE_STRING);
        returnValue = returnValue + cell.getStringCellValue();
        log.info("returnValue:" + returnValue);
        return returnValue;
    }

    /**
     * 读取单元格里面的值
     * <p>
     * //* @param cell
     * //* @return
     * //
     */
    //public String getCellValue(Cell cell) {
    //    String cellValue = "";
    //    if (cell == null) {
    //        return cellValue;
    //    }
    //
    //    cellValue = String.valueOf()
    //    //把数字当成String来读，避免出现1读成1.0的情况
    //    if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
    //        cell.setCellType(Cell.CELL_TYPE_STRING);
    //    }
    //    //判断数据的类型
    //    switch (cell.getCellType()) {
    //        case Cell.CELL_TYPE_NUMERIC: //数字
    //            cellValue = String.valueOf(cell.getNumericCellValue());
    //            break;
    //        case Cell.CELL_TYPE_STRING: //字符串
    //            cellValue = String.valueOf(cell.getStringCellValue());
    //            break;
    //        case Cell.CELL_TYPE_BOOLEAN: //Boolean
    //            cellValue = String.valueOf(cell.getBooleanCellValue());
    //            break;
    //        case Cell.CELL_TYPE_FORMULA: //公式
    //            cellValue = String.valueOf(cell.getCellFormula());
    //            break;
    //        case Cell.CELL_TYPE_BLANK: //空值
    //            cellValue = "";
    //            break;
    //        case Cell.CELL_TYPE_ERROR: //故障
    //            cellValue = "非法字符";
    //            break;
    //        default:
    //            cellValue = "未知类型";
    //            break;
    //    }
    //    return cellValue;
    //}
    public static String decoderURL(String value) {
        try {
            value = URLDecoder.decode(value, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        return value;
    }

}
